package gwtappcontainer.server.apis.bigset;

import static gwtappcontainer.server.apis.bigset.OfyService.ofy;
import gwtappcontainer.server.DatastoreNamespaces;
import gwtappcontainer.server.apis.APIException;
import gwtappcontainer.shared.apis.APIResponse.Status;

import java.util.HashSet;
import java.util.Map;

import com.google.appengine.api.NamespaceManager;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Ref;

class BigSetRepository {
	
	private final static String NAMESPACE = DatastoreNamespaces.BIGSET;
	
	static long createNew(long maxElementsInSet) {
		NamespaceManager.set(NAMESPACE);
				
		BigSetEntity entity = new BigSetEntity();
				
		entity.maxElementsInSet = maxElementsInSet;
		
		ofy().save().entity(entity).now();
		
		return entity.id;
	}		
	
	static void addElement(long bigSetId, long element) {
		NamespaceManager.set(NAMESPACE);
		BigSetEntity bigSetEntity = ofy().load()
				.type(BigSetEntity.class).id(bigSetId).get();
		
		if (null == bigSetEntity)
			throw new APIException(Status.ERROR_RESOURCE_DOES_NOT_EXIST, 
					"there is no big set with id [" + bigSetId + "]");
		
		if (bigSetEntity.sets.size() == 0) {			
			SetEntity setEntity = new SetEntity();			
			setEntity.elements.add(element);
			
			ofy().save().entity(setEntity).now();			
			
			bigSetEntity.sets.add(Ref.create(setEntity));											
			ofy().save().entity(bigSetEntity).now();
			return;
		}
		
		int size = bigSetEntity.sets.size();
		SetEntity setEntity = bigSetEntity.sets.get(size - 1).get();
		
		if (setEntity.elements.size() < bigSetEntity.maxElementsInSet) {
			setEntity.elements.add(element);
			ofy().save().entity(setEntity).now();
			return;
		}
		
		setEntity = new SetEntity();
		setEntity.elements.add(element);
		ofy().save().entity(setEntity).now();
		bigSetEntity.sets.add(Ref.create(setEntity));
		ofy().save().entity(bigSetEntity).now();
		
		return;
	}
	
	static HashSet<Long> getAllElements(long bigSetId) {
		NamespaceManager.set(NAMESPACE);
		
		BigSetEntity bigSetEntity = ofy().load()
				.type(BigSetEntity.class).id(bigSetId).get();
		
		if (null == bigSetEntity)
			throw new APIException(Status.ERROR_RESOURCE_DOES_NOT_EXIST, 
					"there is no big set with id [" + bigSetId + "]");
		
		Map<Key<SetEntity>, SetEntity>  all = ofy().load().values(bigSetEntity.sets);
		
		HashSet<Long> universalSet = new HashSet<Long>();
		
		for (SetEntity setEntity : all.values()) {
			universalSet.addAll(setEntity.elements);
		}
						
		return universalSet;
	}
}
